import Observer from './observer.js'
import Compiler from './compiler.js'
/**
 * 包括vue 构造函数，接受各种配置参数等等
 */
export default class Vue {
  constructor(options = {}) {
    this.$options = options;
    this.$data = options.data;
    this.$methods = options.methods;

    this.initRootElement(options);

    // 利用Object.defineProperty将data里的属性注入到vue实例中
    this._proxyData(this.$data);

    // 实例化observe对象，监听数据变化
    new Observer(this.$data);

    // 实例化compiler对象，解析指令和模板表达式/插值表达式 {{ msg }}
    new Compiler(this);
  }

  /**
   * 获取根元素，并存储到vue实例中，简单检查一下传入的el是否合规
   */
  initRootElement(options) {
    if (typeof options.el === "string") {
      this.$el = document.querySelector(options.el);
    } else if (options.el instanceof HTMLElement) {
      this.$el = options.el;
    }

    if (!this.$el) {
      throw new Error("传入的el不合法，请传入css selector或者HTMLElement");
    }
  }

  _proxyData(data) {
    Object.keys(data).forEach((key) => {
      Object.defineProperty(this, key, {
        enumerable: true,
        configurable: true,
        get() {
          return data[key];
        },
        set(newValue) {
          if (newValue === data[key]) {
            return;
          }
          data[key] = newValue;
        },
      });
    });
  }
}
